`include "s:/define.v"
`include "s:/ppdefine.v"
module
#(parameter PPID=32'h0
)
 ppiaddrreq(
input clk,
input rst_n,
input [31:0] instr,
input [31:2] instr_addr,
output reg resp_instr_v,
output reg [31:0] resp_instr,
output reg start_pp,

input [17:2] jmp_to_iaddr,
input branch_taken,
input [2:0]pp_state,

output reg [31:2] instr_req_addr,
output reg instr_req
);
reg [31:2] resp_instr_addr;
wire [31:2] current_iaddr=resp_instr_addr;
wire [7:0] opcode=instr[31:24];
wire [15:0] disp=instr[15:0];
wire [7:0] max_pp_indx=instr[23:16];//only valid when instr is startpp instr

reg req_state;
always @ (posedge clk or negedge rst_n)
begin
    if(~rst_n)
        begin
            req_state<=0;
            start_pp<=1'b0;
				
            instr_req<=0;
            instr_req_addr<=0;
            
            resp_instr_v<=0;
            resp_instr<=0;
            resp_instr_addr<=0;
        end
    else
        begin
            case(req_state)
            1'b0:
                begin                    
                    if(opcode[7:0]=={`SP_INS,`STARTPP} && PPID<=max_pp_indx && pp_state==`PP_IDLE)
                        begin
                            resp_instr_v<=0;
                            instr_req<=1;
                            instr_req_addr<=disp;
                            req_state<=1'b1;
							start_pp<=1'b1;
                        end
                    else if(pp_state==`PP_DEC)
                        begin
                            resp_instr_v<=0;
                            instr_req<=1;
                            instr_req_addr<=branch_taken?jmp_to_iaddr:(current_iaddr+1);
                            req_state<=1'b1;
                        end
                end
            1'b1:
                begin
					start_pp<=0;
                    if(instr_addr==instr_req_addr)
                    begin
                        resp_instr_v<=1;
                        resp_instr<=instr[31:0];
                        resp_instr_addr<=instr_addr;
                        instr_req<=0;
                        req_state<=1'b0;
                    end
                end
            default:
                begin
                    req_state<=0;
						  start_pp<=0;
                    instr_req<=0;
                    instr_req_addr<=0;
                    
                    resp_instr_v<=0;
                    resp_instr<=0;
                    resp_instr_addr<=0;
                end
            endcase
            
            
        end
end

endmodule
